package cn.xydpeng.springframework.beans.factory.config;

import cn.xydpeng.springframework.beans.BeansException;
import cn.xydpeng.springframework.beans.PropertyValues;
import cn.xydpeng.springframework.lang.Nullable;

/**
 * Subinterface of {@link BeanPostProcessor} that adds a before-instantiation callback,
 * and a callback after instantiation but before explicit properties are set or
 * autowiring occurs.
 *
 * @author xydpeng
 * @version v1.0
 * @date: 2022/10/22
 * @description:
 */
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

    /**
     * bean实例化之前被执行，扩展点钩子
     */
    @Nullable
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    /**
     *  bean实例化之后被执行，but before Spring property population --- 在注入属性之前
     */
    default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }

    /**
     * Post-process the given property values before the factory applies them
     * to the given bean.
     * <p>The default implementation returns the given {@code pvs} as-is.
     * @param pvs the property values that the factory is about to apply (never {@code null})
     * @param bean the bean instance created, but whose properties have not yet been set
     * @param beanName the name of the bean
     * @return the actual property values to apply to the given bean (can be the passed-in
     * PropertyValues instance), or {@code null} to skip property population
     * @throws org.springframework.beans.BeansException in case of errors
     * @since 5.1
     */
    @Nullable
    default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
            throws BeansException {

        return pvs;
    }


}
